package com.gitee.wsl.transform.escape.sample

import com.gitee.wsl.transform.escape.Escape
import com.gitee.wsl.transform.escape.EscapeString

object JavaEscape  : EscapeString() {

    override fun escape(base: String): String {
        return escapeJava(base)?:base
    }

        /**
         * 通用的escape函数，将指定的特殊字符映射到对应的字符串。escapeXml/escapeJson/escapeSql等都采用这个函数实现
         *
         * @param str       待编码的字符串
         * @param fromChars 需要转义的字符列表
         * @param toStrs    转义后的字符串列表，它和fromChars一一对应
         * @return 转义后的字符串
         */
        fun escape(str: CharSequence?, fromChars: CharArray?, toStrs: Array<String?>?): String? {
            if (str == null || str.isEmpty() || fromChars == null || fromChars.isEmpty()) return str?.toString()

            if (toStrs == null || fromChars.size != toStrs.size)
                throw IllegalArgumentException("escape fromChars and toChars length not match")

            val sz = str.length
            var buf: StringBuilder? = null
            for (i in 0 until sz) {
                val ch = str[i]

                val idx = _indexOf(fromChars, ch)
                if (idx < 0) {
                    buf?.append(ch)
                } else {
                    if (buf == null) {
                        buf = StringBuilder(2 * sz)
                        if (i > 0) buf.append(str.subSequence(0, i))
                    }
                    buf.append(toStrs[idx])
                }
            }
            if (buf == null) return str.toString()
            return buf.toString()
        }

         fun _indexOf(chars: CharArray, c: Char): Int {
            var i = 0
            val n = chars.size
            while (i < n) {
                if (chars[i] == c) return i
                i++
            }
            return -1
        }

        val JAVA_ESCAPE_CHARS: CharArray = charArrayOf('\b', '\r', '\n', '\t', '\u000c', '"', '\'', '\\')

        val JAVA_ESCAPE_STRS: Array<String?> = arrayOf("\\b", "\\r", "\\n", "\\t", "\\f", "\\\"", "\\'", "\\\\")

        /**
         * java语言规范中定义的字符串转义
         */
        fun escapeJava(str: String?): String? {
            return escape(str, JAVA_ESCAPE_CHARS, JAVA_ESCAPE_STRS)
        }
}

val Escape.Companion.java
    get() = JavaEscape